package me.alex.learnkotlin.learnKT5

import java.util.*

/**
 * 学习空指针检查 let函数 函数参数默认值
 */

var context: String? = "hello"
fun main() {

    //1.1 可空类型写法 在泛型后加"?"
    //添加"?"后可以不用if(obj != null)的判空逻辑
    doTest(null)

    //1.2 判空辅助 ?: 操作符
    //if判断写法
    getTextLength("asdasdasd")
    //Kotlin写法 首先使用返回值简写的方法 然后text后用?.操作符 配合?:判断符 如果text是null 则返回0
    //?.负责text对象的空安全   ?:负责text对象null以后的逻辑 类似三元表达式 ( text != null ? text.length : 0 )
    getTextLength1("asdasdasd")

    //1.3 非空断言
    //context初始化的时候添加?关键字认为是可空的 但是又赋值了
    //所以调用printUpperCase方法时,但是编译器不知道已经赋值 还是认为有空指针风险, 需要在context后加!!非空断言关键字
    if (context != null) {
        printUpperCase()
    }

    //1.4 let函数
    //为了避免1.1中doTest方法每行都要用?.操作符 使用let函数
    //如果操作的函数很多 避免每次操作test对象都要用?. 简化写法
    doTest1(null)

    //1.5 函数默认值
    //指定了第二个String参数的默认值,这里只需要输入第一个参数即可 第二个参数默认为hello
    printParams(10)
    //如果是第一个参数默认,第二个参数无默认,则需要使用键值对的写法 顺序可以更换
    /**
     * 重点     且 如果所有参数都指定默认值,则可以自由指定参数实现任意参数触发主构造函数
     */
    printParams1(str = "hello")
    printParams1(str = "hello", num = 50)
}

fun printParams(num: Int, str: String = "hello") {
    println("num = $num , str = $str")
}

fun printParams1(num: Int = 10, str: String) {
    println("num = $num , str = $str")
}

fun doTest1(test: Test?) {
    test?.let {
        it.test1()
        it.test2()
        it.test3()
        it.test4()
        it.test5()
    }
}

fun printUpperCase() {
    val upperCase = context!!.toUpperCase(Locale.ROOT)
    println(upperCase)
}

fun getTextLength(text: String?): Int {
    if (text != null) {
        return text.length
    }
    return 0
}

fun getTextLength1(text: String?) = text?.length ?: 0


fun doTest(test: Test?) {
    test?.test1()
    test?.test2()
}

class Test {
    fun test1() {
        println("test1")
    }

    fun test2() {
        println("test2")
    }

    fun test3() {
        println("test3")
    }

    fun test4() {
        println("test4")
    }

    fun test5() {
        println("test5")
    }
}